package net.jansensan.as3maxlikeui
{
	// + ----------------------------------------
	//		[ IMPORTS ]
	// + ----------------------------------------
	
	import flash.display.GradientType;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.geom.Matrix;
	import flash.text.TextField;
	import flash.text.TextFieldAutoSize;
	import flash.text.TextFormat;
	
	
	/**
	 * @author Mat Janson Blanchet
	 */
	public class MessageBox extends Sprite implements IMaxLikeObject
	{
		// + ----------------------------------------
		//		[ CONSTANTS ]
		// + ----------------------------------------
		
		// states
		
		// events
		
		// private
		private	const	HEIGHT			:uint = 24;
		private	const	GRADIENT_COLORS	:Array = [0xb2b2b2, 0xdddddd];
		private	const	GRADIENT_ALPHAS	:Array = [1, 1];
		private	const	GRADIENT_RATIOS	:Array = [0x00, 0xFF];
		private	const	CORNER_RADIUS	:uint = 12;
		
		// static
		
		
		// + ----------------------------------------
		//		[ VARIABLES ]
		// + ----------------------------------------
		
		// display objects
		private	var	_hitArea		:Sprite;
		private	var	_whiteBg		:Sprite;
		private	var	_gradientBg		:Sprite;
		private	var	_bgMask			:Sprite;
		private	var	_format			:TextFormat;
		private	var	_labelTXT		:TextField;
		
		// private / protected
		private	var	_label			:String;
		private	var	_gradientMatrix	:Matrix;
		
		
		// + ----------------------------------------
		//		[CONSTRUCTOR ]
		// + ----------------------------------------
		
		/**
		 * A button that looks like <a href="http://cycling74.com/products/maxmspjitter/" target="_blank">Max 5</a>'s message box.
		 * 
		 * @param label The label displayed in the message box.
		 */
		public function MessageBox(label:String)
		{
			super();
			_label = label;
		}
		
		
		// + ----------------------------------------
		//		[ PUBLIC METHODS ]
		// + ----------------------------------------
		
		/**
		 * Initializes the MessageBox. Call this function before adding the instance on the stage.
		 */
		public function init():void
		{
			_format = new TextFormat();
			_format.font = "Arial";
			_format.size = 16;
			
			_labelTXT = new TextField();
			_labelTXT.defaultTextFormat = _format;
			_labelTXT.htmlText = _label;
			_labelTXT.autoSize = TextFieldAutoSize.LEFT;
			_labelTXT.mouseEnabled = false;
			_labelTXT.x = 3;
			_labelTXT.y = 1;
			
			_whiteBg = new Sprite();
			_whiteBg.graphics.beginFill(0xffffff);
			_whiteBg.graphics.drawRoundRect(0, 0, _labelTXT.width + CORNER_RADIUS * 0.5, HEIGHT, CORNER_RADIUS, CORNER_RADIUS);
			_whiteBg.graphics.endFill();
			
			_bgMask = new Sprite();
			_bgMask.graphics.beginFill(0x000000);
			_bgMask.graphics.drawRoundRect(0, 0, _whiteBg.width, _whiteBg.height, CORNER_RADIUS, CORNER_RADIUS);
			_bgMask.graphics.endFill();
			
			_gradientMatrix = new Matrix();
			_gradientMatrix.createGradientBox(HEIGHT, HEIGHT, -Math.PI/2);
			
			_gradientBg = new Sprite();
			_gradientBg.graphics.beginGradientFill(GradientType.LINEAR, GRADIENT_COLORS, GRADIENT_ALPHAS, GRADIENT_RATIOS, _gradientMatrix);
			_gradientBg.graphics.drawRoundRect(0, 0, _whiteBg.width, _whiteBg.height, CORNER_RADIUS, CORNER_RADIUS);
			_gradientBg.graphics.endFill();
			_gradientBg.mask = _bgMask;
			
			_hitArea = new Sprite();
			_hitArea.graphics.beginFill(0x000000, 0);
			_hitArea.graphics.drawRect(0, 0, _bgMask.width, _bgMask.width);
			_hitArea.graphics.endFill();
			
			addEventListener(Event.ADDED_TO_STAGE, addedToStageHandler, false, 0, true);
			
			addChild(_whiteBg);
			addChild(_gradientBg);
			addChild(_bgMask);
			addChild(_labelTXT);
			addChild(_hitArea);
		}
		
		
		public function show():void
		{
			visible = true;
		}
		
		
		public function hide():void
		{
			visible = false;
		}
		
		
		public function kill():void
		{
			removeEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
			addEventListener(Event.REMOVED_FROM_STAGE, removedToStageHandler, false, 0, true);
			if(_hitArea && _hitArea.hasEventListener(MouseEvent.MOUSE_DOWN))
			{
				_hitArea.addEventListener(MouseEvent.MOUSE_DOWN, mouseHandler, false, 0, true);
			}
			if(stage && stage.hasEventListener(MouseEvent.MOUSE_UP))
			{
				stage.addEventListener(MouseEvent.MOUSE_UP, mouseHandler, false, 0, true);
			}
		}
		
		
		// + ----------------------------------------
		//		[ PRIVATE/PROTECTED METHODS ]
		// + ----------------------------------------
		
		
		
		
		// + ----------------------------------------
		//		[ EVENT HANDLERS ]
		// + ----------------------------------------
		
		private function addedToStageHandler(event:Event):void
		{
			removeEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
			addEventListener(Event.REMOVED_FROM_STAGE, removedToStageHandler, false, 0, true);
			if(_hitArea) _hitArea.addEventListener(MouseEvent.MOUSE_DOWN, mouseHandler, false, 0, true);
			if(stage) stage.addEventListener(MouseEvent.MOUSE_UP, mouseHandler, false, 0, true);
		}
		
		
		private function removedToStageHandler(event:Event):void
		{
			removeEventListener(Event.REMOVED_FROM_STAGE, removedToStageHandler);
			addEventListener(Event.ADDED_TO_STAGE, addedToStageHandler, false, 0, true);
			if(_hitArea) _hitArea.removeEventListener(MouseEvent.MOUSE_DOWN, mouseHandler);
			if(stage) stage.removeEventListener(MouseEvent.MOUSE_UP, mouseHandler);
		}
		
		
		private function mouseHandler(event:MouseEvent):void
		{
			switch(event.type)
			{
				case MouseEvent.MOUSE_DOWN:
					_labelTXT.x = 4;
					_labelTXT.y = 2;
					_gradientBg.alpha = 0.75;
					break;
				
				case MouseEvent.MOUSE_UP:
					_gradientBg.alpha = 1;
					_labelTXT.x = 3;
					_labelTXT.y = 1;
					break;
				
				default :
					break;
			}
		}
		
		
		// + ----------------------------------------
		//		[ GETTERS / SETTERS ]
		// + ----------------------------------------
		
		override public function get width():Number
		{
			return _hitArea.width;
		}
		
		
		override public function get height():Number
		{
			return HEIGHT;
		}
		
		
	}
}